#ifndef PLANE_H
#define PLANE_H

#define PLANE_IMPLEMENTATION
#include "image.hpp"
#include "utils.h"

typedef struct Plane {
  // Plane
  Image image;

  // Shadow
  Image shadow;
  SDL_Point shadowOffset;

  // Direction
  Direction direction;

  // Speed in pixel/second
  int speed;

  // Margin
  int margin;
} Plane;

bool Plane_load(SDL_Renderer *renderer, Plane *plane, const char *image,
                const char *shadow);
void Plane_destroy(Plane *plane);

void Plane_setX(Plane *plane, int x);
void Plane_setY(Plane *plane, int y);
void Plane_setCoordinates(Plane *plane, int x, int y);

void Plane_moveX(Plane *plane, int x);
void Plane_moveY(Plane *plane, int y);

void Plane_move(Plane *plane, int screenWidth, int screenHeight, int framerate);

void Plane_setDirection(Plane *plane, SDL_Keycode keycode);
void Plane_unsetDirection(Plane *plane, SDL_Keycode keycode);

void Plane_render(SDL_Renderer *renderer, Plane *plane);

#endif // header file protect

#ifdef PLANE_IMPLEMENTATION // impl ?

bool Plane_load(SDL_Renderer *renderer, Plane *plane, const char *image,
                const char *shadow) {
  if (!Image_load(renderer, &plane->image, image))
    return false;

  if (!Image_load(renderer, &plane->shadow, shadow)) {
    Image_destroy(&plane->image);
    return false;
  }

  return true;
}

void Plane_destroy(Plane *plane) {
  Image_destroy(&plane->image);
  Image_destroy(&plane->shadow);
}

void Plane_setX(Plane *plane, int x) {
  plane->image.rect.x = x;

  // Plane shadow x coordinate
  plane->shadow.rect.x = plane->image.rect.x +
                         (plane->image.rect.w - plane->shadow.rect.w) / 2 +
                         plane->shadowOffset.x;
}

void Plane_setY(Plane *plane, int y) {
  // Plane y coordinate
  plane->image.rect.y = y;

  // Plane shadow y coordinate
  plane->shadow.rect.y = plane->image.rect.y +
                         (plane->image.rect.h - plane->shadow.rect.h) / 2 +
                         plane->shadowOffset.y;
}

void Plane_setCoordinates(Plane *plane, int x, int y) {
  Plane_setX(plane, x);
  Plane_setY(plane, y);
}

void Plane_moveX(Plane *plane, int x) {
  Plane_setX(plane, plane->image.rect.x + x);
}

void Plane_moveY(Plane *plane, int y) {
  Plane_setY(plane, plane->image.rect.y + y);
}

void Plane_move(Plane *plane, int screenWidth, int screenHeight,
                int framerate) {
  int planeStep = plane->speed / framerate;

  if ((plane->direction & DIRECTION_UP) &&
      plane->image.rect.y - planeStep >= plane->margin) {
    Plane_moveY(plane, -planeStep);
  } else if ((plane->direction & DIRECTION_DOWN) &&
             plane->image.rect.y + plane->image.rect.h + planeStep <=
                 screenHeight - plane->margin) {
    Plane_moveY(plane, planeStep);
  }

  if ((plane->direction & DIRECTION_RIGHT) &&
      plane->image.rect.x + plane->image.rect.w + planeStep <=
          screenWidth - plane->margin) {
    Plane_moveX(plane, planeStep);
  } else if ((plane->direction & DIRECTION_LEFT) &&
             plane->image.rect.x - planeStep >= plane->margin) {
    Plane_moveX(plane, -planeStep);
  }
}

void Plane_setDirection(Plane *plane, SDL_Keycode keycode) {
  // TODO: more key
  switch (keycode) {
  case SDLK_UP:
    // plane->direction &= ~DIRECTION_DOWN;
    plane->direction = DIRECTION_DOWN;
    plane->direction = DIRECTION_UP;
    break;

  case SDLK_DOWN:
    // plane->direction = SDLK_UP;
    plane->direction = DIRECTION_DOWN;
    break;

  case SDLK_RIGHT:
    // plane->direction &= ~SDLK_LEFT;
    plane->direction = DIRECTION_RIGHT;
    break;

  case SDLK_LEFT:
    plane->direction = DIRECTION_RIGHT;
    plane->direction = DIRECTION_LEFT;
    break;
  }
}
void Plane_unsetDirection(Plane *plane, SDL_Keycode keycode) {
  switch (keycode) {
  case SDLK_UP:
    plane->direction = DIRECTION_UP;
    break;

  case SDLK_DOWN:
    plane->direction = DIRECTION_DOWN;
    break;

  case SDLK_RIGHT:
    plane->direction = DIRECTION_RIGHT;
    break;

  case SDLK_LEFT:
    plane->direction = DIRECTION_LEFT;
    break;
  }
}

void Plane_render(SDL_Renderer *renderer, Plane *plane) {
  // Render plane shadow
  Image_render(renderer, &plane->shadow);

  // Render plane
  Image_render(renderer, &plane->image);
}

#endif // do impl ?